package lumis.portal.deployment;

import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;

import lumis.portal.PortalException;
import lumis.portal.PortalObjectNotFoundException;
import lumis.portal.stability.StableMinor;


/**
 * Handles the deployment of portal resources.
 * <p>
 * All methods in this manager execute in their own transaction.
 * 
 * @since 4.0.7
 * @version $Revision: 13093 $ $Date: 2011-05-28 18:40:18 -0300 (Sat, 28 May 2011) $
 */
@StableMinor(version = "6.0", sinceVersion = "6.0")
public interface IDeploymentManager
{
	/**
	 * Register a deployer that may be used when performing a deployment. 
	 * @param deployer the deployer.
	 * @since 4.0.7
	 * 
	 * @deprecated Since 5.0.0 the use of {@link IPortalDeployer}
	 * has been deprecated.
	 */
	@Deprecated
	public void registerDeployer(IPortalDeployer deployer);

	/**
	 * Unregisters a deployer that may be used when performing a deployment.
	 * @param deployer the deployer.
	 * @return
	 * @since 4.0.7
	 * 
	 * @deprecated Since 5.0.0 the use of {@link IPortalDeployer}
	 * has been deprecated.
	 */
	@Deprecated
	public boolean unregisterDeployer(IPortalDeployer deployer);

	/**
	 * Returns the deployer to be used to deploy to the portal.
	 * @param deployConfig the deployment specification.
	 * @return the deployer.
	 * @throws PortalException if there is no deployer that can handle the
	 * specified deployment.
	 * @since 4.0.7
	 * 
	 * @deprecated Since 5.0.0 the use of {@link IPortalDeployer}
	 * has been deprecated.
	 */
	@Deprecated
	public IPortalDeployer getPortalDeployer(DeployConfig deployConfig) throws PortalException;
	
	/**
     * Returns the <code>Class</code> object associated with the class or
     * interface with the given string name, within the deployed JAR library
     * modules or the shared level class loader.
 	 * 
	 * @param className the fully qualified name of the desired class.
     * @return the <code>Class</code> object for the class with the specified name.
	 * @throws ClassNotFoundException if the class cannot be located.
	 * @see {@link Class#forName(String)}
	 * @since 5.0.0
	 * 
	 * @deprecated Since 6.0.0 deployed resources or classes should 
	 * be accessed using the class loader provided by {@link #getClassLoader()}.
	 * Uses of {@link #getClass(String) IDeploymentManager.getClass(className)} 
	 * method may be replaced by 
	 * {@link #getClassLoader() IDeploymentManager.getClassLoader()}.{@link ClassLoader#loadClass(String) loadClass(className)}.
	 */
	@Deprecated
	public Class<?> getClass(String className) throws ClassNotFoundException;
	
	/**
	 * Returns a class loader that provides access to classes and resources
	 * in all deployed JAR modules and the portal.
	 * <p>
	 * When the returned class loader is used to obtain a class,
	 * the search is first done in the currently running modules and then in the 
	 * portal main class loader.
	 * <p>
	 * When the returned class loader is used to obtain a resource,
	 * the search is first done in the <code>lumisdata/def</code> folder 
	 * (for backwards compatibility), then in currently running modules and 
	 * then in the portal main class loader.
	 * <p>
	 * Main uses are:
	 * <ul>
	 * <li>{@link ClassLoader#loadClass(String)}: for obtaining a {@link Class}.</li>
	 * <li>{@link ClassLoader#getResourceAsStream(String)}, {@link ClassLoader#getResource(String)} or {@link ClassLoader#getResources(String)}:
	 * for accessing resources.</li>
	 * </ul>
	 * @return the class loader.
	 * @since 6.0.0
	 */
	public ClassLoader getClassLoader();
	
	/**
	 * Detects the module type of an archive, based on its contents.
	 * @param moduleArchive the archive content input stream.
	 * @return the module type.
	 * @throws IOException if an I/O error occurs.
	 * @throws IllegalModuleArchiveException if the archive module type 
	 * could not be recognized.
	 * @since 5.0.0
	 */
	public ModuleType detectModuleType(InputStream moduleArchive) 
			throws IOException, IllegalModuleArchiveException, PortalException;
	
	/**
	 * Distributes a module archive to the portal servers. This operation 
	 * validates the archive, generates all container specific classes and 
	 * interfaces, and moves the resulting archive to all portal server nodes.
	 * @param moduleId the identifier for the module being deployed.
	 * @param moduleArchive the module archive input stream.
	 * @return the deployed module object.
	 * @throws IOException if an I/O error occurs.
	 * @throws IllegalModuleArchiveException if the archive module type 
	 * could not be recognized.
	 * @since 5.0.0
	 */
	public IModule distribute(String moduleId, InputStream moduleArchive) 
			throws IOException, IllegalModuleArchiveException, PortalException;

	/**
	 * Starts the execution of a module. If the module is already running it
	 * is not affected.
	 * @param module the module.
	 * @since 5.0.0
	 */
	public void start(IModule module) throws PortalException;
	
	/**
	 * Stops the execution of a module. If the module is not running it is 
	 * not affected.
	 * @param module the module.
	 * @since 5.0.0
	 */
	public void stop(IModule module) throws PortalException;
	
	/**
	 * Undeploys a module from the portal servers.
	 * @param module the module to be undeployed.
	 * @since 5.0.0
	 */
	public void undeploy(IModule module) throws PortalException;
	
	/**
	 * Returns the currently installed modules of the specified type.
	 * @param moduleType the module type.
	 * @return the modules. 
	 * @since 5.0.0
	 */
	public Collection<IModule> getModules(ModuleType moduleType) throws PortalException;
	
	/**
	 * Returns the module with the specified identifier.
	 * @param moduleId the module identifier.
	 * @return the module.
	 * @throws PortalObjectNotFoundException if no module with the given 
	 * identifier was found.
	 * @since 5.0.0
	 */
	public IModule getModule(String moduleId) throws PortalException;
}